﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using XDL.Framework;
using XDL.Framework.Particles;

namespace JumpNFight.Simulation
{
    class FlyingBadGuy : 
        BadGuy
    {
        ParticleEmitter m_rightEmitter;
        ParticleEmitter m_leftEmitter;
        // ParticleSystem m_enginePS;
        int m_targetIndex;
        List<Vector2i> m_path;
        AudioManager m_audio;

        public List<Vector2i> Path
        {
            get
            {
                return m_path;
            }
        }

        public const int SpawnFlyingBadGuyEvent = 7001;
        public bool RefreshPath = true;

        public override int NPCType
        {
            get
            {
                return 2;
            }
        }

        FlyingMoveable m_moveable;
        public override Moveable Moveable
        {
            get
            {
                return m_moveable;
            }
        }

        static Vector3 g_leftTrust;
        static Vector3 g_rightTrust;
        static FlyingBadGuy()
        {
            g_leftTrust = Vector3.Normalize(new Vector3(-1, 1, 0));
            g_rightTrust = Vector3.Normalize(new Vector3(1, 1, 0));
        }

        public FlyingBadGuy(int id, Game game, PlayerIndex targetIndex) :
            base(id,game)
        {
            m_targetIndex = (int)targetIndex;
            Health = 50;
            m_moveable = new FlyingMoveable(id);
            m_moveable.Width = 16;
            m_moveable.Height = 16;
            m_moveable.Mass = 150;
            m_moveable.MaxSpeed = 90;

            //
            ParticleSystem ps = GameServices.GetService<ParticleSystem>("Particles/FusionEngine");
            m_leftEmitter = new ParticleEmitter(ps, 25);
            m_rightEmitter = new ParticleEmitter(ps, 25);
            m_audio = GameServices.GetService<AudioManager>();
        }

        protected override void Kill(GameTime gameTime, Vector2 velocity)
        {
            // use "balistic" behavior if dead!
            m_moveable.IsBalistic = true;
            base.Kill(gameTime, velocity);
        }

        Player PickNextPlayer()
        {
            for (int i = 0; i < World.MaxPlayers; i++)
            {
                Player p = World.Players[i];
                if ( m_targetIndex != i && p.IsAlive)
                {
                    m_targetIndex = i;
                    return p;
                }
            }
            return null;
        }

        public override void Update(GameTime gameTime)
        {
            if (IsAlive)
            {
                Player nearestPlayer = World.Players[(int)m_targetIndex];
                if (!nearestPlayer.IsAlive)
                    nearestPlayer = PickNextPlayer();
                if (nearestPlayer != null && nearestPlayer.IsAlive)
                {
                    Vector2 move = nearestPlayer.Position - Moveable.Position;
                    float playerDistanceSquared = move.LengthSquared();
                    // are we near enough?
                    if (playerDistanceSquared > 0)
                    {
                        // find the best path to the player
                        move = Vector2.Zero;
                        if (RefreshPath)
                        {
                            m_path = World.GetPath(this.Moveable, nearestPlayer.Position);
                            RefreshPath = true;
                        }

                        // check if path is not longer than max allowed distance
                        if (m_path != null &&
                            m_path.Count > 0)
                        {
                            Vector2 worldPathPos = World.MapCenterToWorldUnit(m_path[0]);
                            // reach a path node? remove it from the list
                            if (Vector2.DistanceSquared(worldPathPos, Moveable.Position) < 0.25f)
                                m_path.RemoveAt(0);
                            // move to the next tile center
                            move = worldPathPos - Moveable.Position;
                        }
                    }
                    //
                    if (move.LengthSquared() > 0)
                        move.Normalize();
                    move.Y += (float)Math.Cos(10 * gameTime.TotalGameTime.TotalSeconds - ID);
                    Moveable.Move(move);
                }


                m_leftEmitter.Update(gameTime, new Vector3(m_moveable.X - 8, m_moveable.Y, 0), g_leftTrust);
                m_rightEmitter.Update(gameTime, new Vector3(m_moveable.X + 8, m_moveable.Y, 0), g_rightTrust);

                m_audio.PlayCue("FlyingBadGuy/Ambient");
            }
            base.Update(gameTime);
        }
    }
}
